<template>
    <h1>Watch用法</h1>
    <div class="container">
        求和: {{sum}}
        <br>
        <button @click="add">+1</button>
        <slot></slot>
        <slot name="slot1"></slot>
        <slot name="slot2" :options="person"></slot>
        <hr>
        <h2>情况二:监视[ref]定义的[对象类型]数据</h2>
        <h3>姓名:{{person.name}}</h3>
        <h3>年龄:{{person.age}}</h3>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="changePerson">修改整个人</button>
        <hr>
        <h2>情况三:监视[reactive]定义的[对象类型]数据,且默认开启了[深度监听]</h2>
        <h3>姓名:{{student.name}}</h3>
        <h3>年龄:{{student.age}}</h3>
        <button @click="changeSName">修改名字</button>
        <button @click="changeSAge">修改年龄</button>
        <button @click="changeStudent">修改整个人</button>
        <hr>
        <h2>情况四:监视响应式对象中的某个属性</h2>
        <h4>姓名:{{person1.name}}</h4>
        <h4>年龄:{{person1.age}}</h4>
        <h4>车辆:{{person1.car.c1}}、{{ person1.car.c2 }}</h4>
        <button @click="changeP1Name">修改名字</button>
        <button @click="changeP1Age">修改年龄</button>
        <button @click="changeP1Car1">修改第一台车</button>
        <button @click="changeP1Car2">修改第二台车</button>
        <button @click="changeCar">修改整辆车</button>
        <h4></h4>
    </div>
  
    
</template>

<script setup lang="ts">
import { reactive, ref,watch } from 'vue';
let sum = ref(0);
let person = ref({
    name:'张三',
    age:18
})
function add(){
    sum.value++;
}
// 监视函数有一个默认的返回值:停止监视,这里可以声明一个变量接收watch的返回值,然后打印变量查看返回值
const stopWatch = watch(sum,(newVal,oldVal)=>{
    console.log('sum的值变化了',newVal,oldVal);
    if(newVal > 10){
        stopWatch();
    }
})

function changeName(){
    person.value.name += '~'
}
function changeAge(){
    person.value.age += 1;
}
function changePerson(){
    person.value = {name:'李四',age:20}
}
// 监视[ref]定义的[对象类型]数据,监视的是对象的[引用地址]
// 注意：·若修改的是[ref]定义的对象中的属性,newValue和oldValue都是新值,因为他们是同一个对象
watch(person,(newVal,oldVal)=>{
    console.log(newVal,oldVal);
},{deep:true})

let student = reactive({
    name:'张三',
    age:18
})
function changeSName(){
    student.name += '~'
}
function changeSAge(){
    student.age += 1;
}
function changeStudent(){
    student = Object.assign(student,{name:'李四',age:20}) 
}
// 监视[reactive]定义的[对象类型]数据,默认开启深度监视(不用再配置deep:true)
watch(student,(newVal,oldVal)=>{
    console.log(newVal,oldVal);
})



let person1 = reactive({
  name:'王五',
  age:20,
  car:{
    c1:'领克',
    c2:'沃尔沃'
  }  
})
function changeP1Name(){
    person1.name += '~'
}
function changeP1Age(){
    person1.age += 1;
}
function changeP1Car1(){
    person1.car.c1 = '奥迪'
}
function changeP1Car2(){
    person1.car.c2 = '奔驰'
}
function changeCar(){
    person1.car = {c1:'雅迪',c2:'九号'}
}
// watch函数,只能监听,一个有返回值的函数(getter函数),一个ref(ref定义的数据),一个响应式的对象(reactive定义的数据),或者是由前边类型的值组成的数组


// 监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
watch(()=>person1.name,() => { 
    // console.log('person1.name被修改了');
})
// 根据上述的函数可以知道这个地方可以直接写person1.car的因为是一个对象,为什么要写成函数返回式呢,因为如果要整个改变person对线中的car对象是直接改变了地址,所以监视不到.
// 因为你在外边包含了一个函数,所以就指定这个地址了,所以他们监视的就是同一个地址了
// watch(()=>person1.car,(newVal,oldVal) => { console.log(newVal,oldVal);},{deep:true})
// 第五种情况 监视多个基础数据变量
watch([()=>person1.name,()=>person1.car.c1],(newVal,oldVal) => { console.log(newVal,oldVal);},{deep:true})
</script>

<style scoped>
    .container{
        /* background-color: seashell; */
        background: linear-gradient(315deg, #42d392 25%, #647eff);
        box-shadow: 0 0 10px;
        border-radius: 10px;
        padding: 20px;
    }
</style>